﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Threading;
using DelphiConverterLibrary;

namespace Source2HTML
{
    /// <summary>
    /// Главный класс приложения, управляющий всем процессом
    /// </summary>
    class Program
    {
        /// <summary>
        /// Точка входа в программу и главный управляющий метод
        /// </summary>
        /// <param name="args"> строка параметров из командной строки
        /// tohtml filename –key [:value]
	    ///     filename - имя или маска для файла или набора файлов. 
	    ///-e - исключение некоторых файлов
        ///     value - маски для необрабатываемых файлов
        ///-r - рекурсивный обход поддиректорий
        ///-ssi - представление вывода в формате, подходящем для вставки в веб-страницу
	    ///-o - задать директорию для выходных файлов
		///     value - имя директории
    	///-mshelp - создать файлы проекта Microsoft Help Workshop
    	///-l - вручную задать используемый язык программирования
		///     value - значение из набора [csharp,delphi,java] 
        ///-s - вручную задать файл используемой цветовой схемы
      	///	    value - имя файла
        ///-ic – включить css-файл в тело выходного html-документа
        /// </param>
        static void Main(string[] args)
        {
            bool recursive = false;
            bool ssi = false;
            bool mshelp = false;
            string excludePattern = null;
            string lang = "";
            bool includeCss = false;
            System.Reflection.Assembly app = System.Reflection.Assembly.GetEntryAssembly();
            string baseDir = System.IO.Path.GetDirectoryName(app.Location);
            string css = baseDir + @"\res\style.css";
            string outputDir = Directory.GetCurrentDirectory() + @"\sourceHTML";
            foreach (string param in args)
            {
                char[] separators = new char[1];
                separators[0] = ':';
                string[] keyAndValue = param.Split(separators, 2);
                    switch (keyAndValue[0])
                {
                    case "-e":
                        try
                        {
                            excludePattern = keyAndValue[1];
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Нет значения для -e");
                            return;
                        }
                        break;
                    case "-r":
                        recursive = true;
                        break;
                    case "-ssi":
                        ssi = true;
                        break;
                    case "-o":
                        try
                        {
                            outputDir = keyAndValue[1];
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Нет значения для -o");
                            return;
                        }
                        break;
                    case "-mshelp":
                        mshelp = true;
                        break;
                    case "-l":
                        try
                        {
                            lang = keyAndValue[1];
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Нет значения для -l");
                            return;
                        }
                        break;
                    case "-s":
                        try
                        {
                            css = keyAndValue[1];
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Нет значения для -s");
                            return;
                        }
                        break;
                    case "-ic":
                        includeCss = true;
                        break;
                }
                
            }


            try
            {
                List<DictionaryEntry> files = Utils.CreateFileStruct(outputDir, args[0], excludePattern, recursive, includeCss ? null : css);
                List<string> outFiles = new List<string>();
                if (ssi && files.Count != 1)
                {
                    Console.WriteLine("SSI доступен для одного файла");
                    return;
                }
                switch (lang.ToLower())
                {
                    case "delphi":
                        DelphiConverter dc = new DelphiConverter();
                        foreach (DictionaryEntry element in files)
                        {
                            Console.WriteLine("convert " + element.Key.ToString() + " to " + element.Value.ToString());
                         //   dc.Convert(element.Key.ToString(), element.Value.ToString(), ssi);
                            string cssName = "style.css";
                            if (includeCss)
                            {
                                cssName = css;
                            }
                            dc.Convert(element.Key.ToString(), element.Value.ToString(), cssName, includeCss, ssi);
                         //   dc.Convert(
                            outFiles.Add(element.Value.ToString());
                        }
                        break;
                }
                if (ssi)
                {
                    StreamReader sr = new StreamReader(File.OpenRead(outFiles[0]));
                    sr.Close();
                   DirectoryInfo dir =  new DirectoryInfo(Path.GetDirectoryName(outFiles[0]));
                   dir.Delete(true);
                    return;
                }
                
                List<string> folders = new List<string>();
              //  outFiles.Sort();
                string beginHTML = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">  <title>Главная страница </title> <script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script><script type=\"text/javascript\">google.load(\"jquery\", \"1.4.3\");google.setOnLoadCallback(function() {$(\".folderShow\").live(\"click\", function() {$(this).text(\"Свернуть\");$(this).attr(\"className\", \"folderHide\");		var foldername = $(this).parent().attr(\"id\");    $(\"#\"+foldername+\"Details\").show();         });      $(\".folderHide\").live(\"click\", function() {    $(this).text(\"Развернуть\");    $(this).attr(\"className\", \"folderShow\");	var foldername = $(this).parent().attr(\"id\");		$(\"#\"+foldername+\"Details\").hide();  });$(\"body\").ready(function() {}); });	</script> </head>   <body> ";
                string openFolder = "<span id=\"{nameFolder}\"> {nameFolderTitle} <span class='folderHide'>Свернуть</span> </span><br> <div id=\"{nameFolder}Details\" style=\"left:0px\"> ";
                string closeFolder = "</div>";
                string endHTML = "</body></html>";
                string contentFolder = "<a href = {pathSrc} >{nameSrc} </a><br>";

                string beginMS = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\"><HTML><HEAD><meta name=\"GENERATOR\" content=\"Microsoft® HTML Help Workshop 4.1\"><!-- Sitemap 1.0 --></HEAD><BODY><UL>";
                string openFolderMS = "	<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"{nameSrc}\"></OBJECT></LI><UL>";
                string closeFolderMS = "</UL>";
                string contentFolderMS = "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"{nameSrc}\"><param name=\"Local\" value=\"{pathSrc}\"></OBJECT></LI>";
                string endMS = "</UL></BODY></HTML>";
                StreamWriter fsMS = null;
                if (mshelp)
                {
                    fsMS = new StreamWriter(File.Create(baseDir + @"\res\Content.hhc"));
                    fsMS.WriteLine(beginMS);
                }
                StreamWriter fs = new StreamWriter(File.Create(outputDir + "\\index.html"));
                fs.Write(beginHTML);
                
                List<string> openedFolders = new List<string>();
                foreach (string path in outFiles)
                {

                    string folderPath = Path.GetDirectoryName(path).Replace(outputDir, "");
                    if (folders.Count != 0)
                    {
                        for (int i = openedFolders.Count; i > 0; i--)
                        {
                            if (folderPath.IndexOf(openedFolders[i - 1]) == -1)
                            {
                                fs.Write(closeFolder);
                                if (mshelp)
                                    fsMS.WriteLine(closeFolderMS);
                                openedFolders.RemoveAt(i - 1);
                            }
                        }
                        //fs.Write("<br>");

                    }
                    if (!folders.Contains(folderPath))
                    {                        
                        for (int i = 0; i < openedFolders.Count; i++)
                        {
                            fs.Write("&nbsp&nbsp&nbsp&nbsp");
                        }
                        openedFolders.Add(folderPath);
                        fs.Write(openFolder.Replace("{nameFolder}", folderPath.Replace("\\", "")).Replace("{nameFolderTitle}", folderPath.Contains("\\") ? folderPath.Substring(folderPath.LastIndexOf("\\") + 1) : folderPath));
                        if (mshelp)
                            fsMS.Write(openFolderMS.Replace("{nameSrc}", folderPath.Contains("\\") ? folderPath.Substring(folderPath.LastIndexOf("\\") + 1) : folderPath));
                        folders.Add(folderPath);
                    }
                    for (int i = 0; i < openedFolders.Count-1; i++)
                    {
                        fs.Write("&nbsp&nbsp&nbsp&nbsp");
                        
                    }
                    fs.Write(contentFolder.Replace("{pathSrc}", path.Replace(outputDir, "").Substring(1)).Replace("{nameSrc}", path.Substring(path.LastIndexOf("\\") + 1)));
                    if (mshelp)
                        fsMS.Write(contentFolderMS.Replace("{pathSrc}", path).Replace("{nameSrc}", path.Substring(path.LastIndexOf("\\") + 1)));

                }
                for (int i = 0; i < openedFolders.Count; i++)
                {
                    fs.Write(closeFolder);
                    if (mshelp)
                    {
                        fsMS.WriteLine(closeFolderMS);
                    }
                }
                fs.Write(endHTML);
                
                if (mshelp)
                {
                    fsMS.Write(endMS);
                    fsMS.Close();
                    File.Copy(baseDir + "\\res\\main.hhp", outputDir + "\\main.hhp",true);
                    File.Copy(baseDir + "\\res\\Content.hhc", outputDir + "\\Content.hhc", true);
                    File.Copy(baseDir + "\\res\\hhc.exe", outputDir + "\\hhc.exe", true);
                    System.Diagnostics.Process prc = System.Diagnostics.Process.Start(outputDir + "\\hhc.exe ", outputDir + "\\main.hhp");
                    prc.WaitForExit();
                    File.Delete(outputDir + "\\Content.hhc");
                    File.Delete(outputDir + "\\main.hhp");
                    File.Delete(outputDir + "\\hhc.exe");



                }
                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            

                    /*
            string[] dirs = Directory.GetFiles(
            foreach (string dir in dirs)
            {
                Console.WriteLine(dir);
            }  */
        }
    }
}
